package main

import (
	"fmt"
	"net"
)

func main() {
	/*
		net.Conn 接口
				Conn接口代表一个通用的网络连接，可以表示 TCP、UDP 或 Unix 域套接字等连接。
				该接口定义了一些基本的读写方法，例如 Read、Write、Close等。
				在实际使用中，我们可以把 TCPConn、UDPConn 或 UnixConn 对象转换为 Conn 类型，以便实现通用的读写操作。

		3.net包 中的常用函数：
		（1）net.Dial()
			func Dial(network, address string) (Conn, error)
			用于创建一个 客户端（TCP 或 UDP） 连接。
			参数 network 指定网络协议（"tcp" 或 "udp"），address 指定目标地址（如"127.0.0.1:8080"）。
			返回一个 Conn对象 表示连接。

		（2）net.Listen()
			func Listen(network, address string) (Listener, error)
			用于监听一个 TCP 端口。
			参数 network 指定网络协议（"tcp" 或 "udp"），address 指定监听地址（如":8080"表示监听本机所有网卡的8080端口）。
			并返回一个 Listener对象 表示监听器。

		（3）Accept()（Listener接口中的方法）
			func Accept() (Conn, error)
			等待并接受一个客户端连接请求。
			它在有新的客户端连接时，返回一个 Conn对象 和一个 错误对象

		（4）Conn.Write()（Conn接口中的方法）
			func Write(b []byte) (n int, err error)
			向连接中写入数据。
			它接受一个字节数组。
			返回写入的字节数和一个错误对象。

		（5）Read()（Conn接口中的方法）
			func Read(b []byte) (n int, err error)
			从连接中读取数据。
			它接受一个字节数组。
			返回读取的字节数和一个错误对象。

		（6）Close()
			关闭连接 或 监听器。
			Conn.Close()
			Listener.Close()

		（7）net.ResolveTCPAddr()
			func ResolveTCPAddr(network, address string) (*TCPAddr, error)
			解析一个 TCP 地址字符串
			返回一个 TCP 地址对象
				type TCPAddr struct {
					IP   IP
					Port int
					Zone string // IPv6 scoped addressing zone
				}

		（8）net.ResolveUDPAddr()
			func ResolveUDPAddr(network, address string) (*UDPAddr, error)
			解析一个 UDP 地址字符串
			返回一个 UDP 地址对象
				type UDPAddr struct {
					IP   IP
					Port int
					Zone string // IPv6 scoped addressing zone
				}

		（9）net.LookupHost()
			func LookupHost(host string) ([]string, error)
			通过域名获取对应的主机地址列表

		（10）net.LookupIP()
			func LookupIP(host string) ([]net.IP, error)
			通过域名获取对应的 IP 地址列表。


	*/
	//1.Dial()
	conn, err := net.Dial("tcp", "127.0.0.1:8080")
	if err != nil {
		fmt.Println(err)
		return
	}
	defer conn.Close()

	//2.Listen()
	listener, err := net.Listen("tcp", ":8080")
	if err != nil {
		fmt.Println(err)
	}
	defer listener.Close()

	//3.Listener.Accept()
	conn1, err := listener.Accept()
	if err != nil {
		fmt.Println(err)
		return
	}
	defer conn1.Close()

	//4.Conn.Write()
	data := []byte("Hello everybody，我是喜羊羊！")
	n, err := conn1.Write(data)
	if err != nil {
		fmt.Println(err)
		return
	}
	fmt.Println("写入连接的字节数：", n)

	//5.Conn.Read()
	data1 := make([]byte, 1024)
	num, err := conn1.Read(data1)
	if err != nil {
		fmt.Println(err)
		return
	}
	fmt.Println("从连接中读取的字节数：", num)

	//7.net.ResolveTCPAddr
	tcpAddr, err := net.ResolveTCPAddr("tcp", "127.0.0.1:8080")
	if err != nil {
		fmt.Println(err)
		return
	}
	fmt.Println("tcpAddr.IP: ", tcpAddr.IP, "tcpAddr.Zone: ", tcpAddr.Zone, "tcpAddr.Zone: ", tcpAddr.Port)

	//8.net.ResolveUDPAddr()
	udpAddr, err := net.ResolveUDPAddr("udp", "127.0.0.1:8080")
	if err != nil {
		fmt.Println(err)
		return
	}
	fmt.Println("udpAddr.IP: ", udpAddr.IP, "udpAddr.Zone: ", udpAddr.Zone, "udpAddr.Port: ", udpAddr.Port)

	//9.net.LookupHost()
	addrs, err := net.LookupHost("www.google.com")
	if err != nil {
		fmt.Println(err)
		return
	}
	for _, addr := range addrs { //'_'为下标
		fmt.Println(addr)
	}

	//10.net.LookupIP()
	ips, err := net.LookupIP("www.google.com")
	if err != nil {
		fmt.Println(err)
		return
	}
	for _, ip := range ips {
		fmt.Println(ip)
	}

}
